package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

func div(a, b int) (q, r int) {
	return a / b, a % b
}

func main() {
	fmt.Println(div(3, 4))

	q, r := div(5, 6)

	fmt.Println(q, r)

	fmt.Println(
		eval(1, 5, "-"))

	fmt.Println(
		apply(pow, 2, 3))

	fmt.Println(
		apply(
			func(i int, i2 int) int { //匿名函数
				return int(math.Pow(float64(i), float64(i2)))
			}, 3, 4))
	/*
	   输出结果：

	   0 3
	   0 5
	   -4 <nil>
	   calling function main.pow with args (2, 3)
	   8
	   calling function main.main.func1 with args (3, 4)
	   81

	*/
}

func pow(a, b int) int {
	return int(
		math.Pow(
			float64(a), float64(b)))
}

// 原始写法
func eval(a, b int, op string) (int, error) {
	switch op {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":
		return a / b, nil
	default:
		return 0, fmt.Errorf("unsupported operation: %s", op)
	}
}

// 符合函数
func apply(op func(int, int) int, a, b int) int {
	pointer := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(pointer).Name()

	fmt.Printf("calling function %s with args (%d, %d) \n", opName, a, b)
	return op(a, b)
}
